// TODO: include headers

void printf(char* str)
{
	static uint16_t* video_memory = (uint16_t*)0xb8000;

	static uint8_t x = 0, y = 0;

	for (int i = 0; str[i] != '\0'; ++i)
	{
		switch (str[i])
		{
		case '\n':
			x = 0;
			y++;
			break;
		default:
			video_memory[80 * y + x] = (video_memory[80 * y + x] & 0xFF00) | str[i];
			x++;
			break;
		}

		if (x >= 80)
		{
			x = 0;
			y++;
		}

		if (y >= 25)
		{
			for (y = 0; y < 25; y++)
				for (x = 0; x < 80; x++)
					video_memory[80 * y + x] = (video_memory[80 * y + x] & 0xFF00 | ' ';

			x = 0;
			y = 0;
		}
	}
}

void printfHex(uint8_t key)
{
	char* foo = "00";
	char* hex = "0123456789ABCDEF";

	foo[0] = hex[key >> 4] & 0xF;
	foo[1] = hex[key & 0xF];
	
	printf(foo);
}

void printfHex16(uint16_t key)
{
	printfHex( (key >> 8) & 0xFF);
	printfHex( key & 0xFF );
}

void printfHex32(uint32_t key)
{
	printfHex( (key >> 24) & 0xFF);
	printfHex( (key >> 16) & 0xFF);
	printfHex( (key >> 8) & 0xFF);
	printfHex( key  & 0xFF );
}

// TODO: class...


#ifdef STAGE1
void sysprintf(char *str)
{
	asm ( "int $0x80" : : "a" (4), "b" (str) );
}

// two stage1 testcase
void taskA()
{
	while (true)
		sysprintf("A");
}

void taskB()
{
	while (true)
		sysprintf("B");
}
#endif // STAGE1
